﻿using System;
using System.Diagnostics;
using System.Linq;
using System.Security.Cryptography;
using System.Web;
using System.Web.Security;
using Entersoft.Utils;

namespace BCS.MotorActivacion.Models.Repository
{
    public class rpUser
    {
        public bool ChangePassword(string username, string oldPassword, string newPassword)
        {
            using (var db = new dbCS())
            {
                var result = from u in db.Users where (u.UserName == username) select u;

                if (result.Count() == 0)
                    return false;

                var user = result.First();

                if (user.Password != CreatePasswordHash(oldPassword, user.PasswordSalt) && user.IsActivated) 
                    return false;

                user.NewPasswordKey = GenerateKey();
                user.IsActivated = false;
                user.Password = CreatePasswordHash(newPassword, user.PasswordSalt);
                user.LastModifiedDate = DateTime.Now;

                db.SaveChanges();

                return true;
            }
        }

        /// <summary>
        /// 
        /// </summary>
        public static string BaseSiteUrl
        {
            get
            {
                var context = HttpContext.Current;

                return new UriBuilder(context.Request.Url.Scheme, context.Request.Url.Host, context.Request.Url.Port).ToString();
            }

        }

        public MembershipUser CreateUser(string username, string password, string email)
        {
            using (var db = new dbCS())
            {
                var _PasswordSalt = CreateSalt();

                var user = new User
                                {
                                    UserName = username,
                                    Email = email,
                                    Password = CreatePasswordHash(password, _PasswordSalt),
                                    PasswordSalt = _PasswordSalt,
                                    CreatedDate = DateTime.Now,
                                    IsActivated = false,
                                    IsLockedOut = false,
                                    LastLockedOutDate = DateTime.Now,
                                    LastLoginDate = DateTime.Now,
                                    LastLoginIp = HttpContext.Current.Request.UserHostAddress,
                                    NewEmailKey = GenerateKey(),
                                };

                db.AddToUsers(user);
                db.SaveChanges();

                string ActivationLink = BaseSiteUrl + "/Account/Activate/" +
                                     user.UserName + "/" + user.NewEmailKey;

                var _Correo = new Correo();

                _Correo.Enviar("pablo.rodriguez.entersoft@gmail.com", user.Email, "Activar tu cuenta", ActivationLink);

                return GetUser(username);
            }
        }

        public string GetUserNameByEmail(string email)
        {
            using (var db = new dbCS())
            {
                var result = from u in db.Users where (u.Email == email) select u;

                if (result.Count() == 0)
                    return "";

                var dbuser = result.FirstOrDefault();

                Debug.Assert(dbuser != null, "dbuser != null");

                return dbuser.UserName;
            }
        }

        public MembershipUser GetUser(string username)
        {
            MembershipUser user = null;

            using (var db = new dbCS())
            {
                var result = from u in db.Users where (u.UserName == username) select u;

                if (result.Count() == 0)
                    return null;

                var dbuser = result.FirstOrDefault();

                if (dbuser != null)
                {
                    string _username = dbuser.UserName;
                    int _providerUserKey = dbuser.UserId;
                    string _email = dbuser.Email;
                    const string _passwordQuestion = "";
                    string _comment = dbuser.Comments;
                    bool _isApproved = dbuser.IsActivated;
                    bool _isLockedOut = dbuser.IsLockedOut;
                    DateTime _creationDate = dbuser.CreatedDate;
                    DateTime _lastLoginDate = dbuser.LastLoginDate;
                    DateTime _lastActivityDate = DateTime.Now;
                    DateTime _lastPasswordChangedDate = DateTime.Now;
                    DateTime _lastLockedOutDate = dbuser.LastLockedOutDate;

                    user = new MembershipUser("BCSMembershipProvider",
                                                  _username,
                                                  _providerUserKey,
                                                  _email,
                                                  _passwordQuestion,
                                                  _comment,
                                                  _isApproved,
                                                  _isLockedOut,
                                                  _creationDate,
                                                  _lastLoginDate,
                                                  _lastActivityDate,
                                                  _lastPasswordChangedDate,
                                                  _lastLockedOutDate);

                }
            }

            return user;
        }

        private static string CreateSalt()
        {
            var rng = new RNGCryptoServiceProvider();
            var buff = new byte[32];
            rng.GetBytes(buff);

            return Convert.ToBase64String(buff);
        }

        private static string CreatePasswordHash(string pwd, string salt)
        {
            string saltAndPwd = String.Concat(pwd, salt);
            string hashedPwd =
                    FormsAuthentication.HashPasswordForStoringInConfigFile(
                    saltAndPwd, "sha1");
            return hashedPwd;
        }

        public bool ValidateUser(string username, string password)
        {
            using (var db = new dbCS())
            {
                var result = from u in db.Users where (u.UserName == username) select u;

                if (result.Count() != 0)
                {
                    var dbuser = result.First();

                    return dbuser.Password == CreatePasswordHash(password, dbuser.PasswordSalt) && dbuser.IsActivated;
                }
                
                return false;
            }
        }

        private static string GenerateKey()
        {
            Guid emailKey = Guid.NewGuid();

            return emailKey.ToString();
        }

        public bool ActivateUser(string username, string key)
        {
            using (var db = new dbCS())
            {
                var result = from u in db.Users where (u.UserName == username) select u;

                if (result.Count() == 0)
                    return false;
                
                var dbuser = result.First();

                if (dbuser.NewEmailKey != key)
                    return false;
                
                dbuser.IsActivated = true;
                dbuser.LastModifiedDate = DateTime.Now;
                dbuser.NewEmailKey = null;

                db.SaveChanges();

                return true;
            }
        }
    }
}